Skip to content

fix: forward cancellation token to toolkit installer subprocesses#409

Open
sLightlyDev wants to merge 2 commits into
mainfrom
marko/sal-105-hanging-kernel-cant-be-cancelled
Open

fix: forward cancellation token to toolkit installer subprocesses#409
sLightlyDev wants to merge 2 commits into
mainfrom
marko/sal-105-hanging-kernel-cant-be-cancelled

Conversation

@sLightlyDev

@sLightlyDev sLightlyDev commented Jun 9, 2026

Copy link
Copy Markdown

Problem

The pip/venv processService.exec calls in the Deepnote toolkit installer were started without the CancellationToken. Cancellation was only checked between calls, so cancelling during a multi-minute pip install did nothing until the install finished — the Stop button appeared dead.

Fix

Pass the token into every exec call in deepnoteToolkitInstaller.node.ts (and thread it through isToolkitInstalled). The process layer already wires token.onCancellationRequested to kill the subprocess, so cancelling now terminates the running install immediately.

Testing

  • Added unit tests asserting the token is forwarded to exec
  • Full unit suite green (2333 passing, 0 failing)
  • tsc clean
  • Verified manually in the Extension Development Host: with a fresh environment install running, clicking Cancel now stops it within ~1–2s (pip output halts immediately)

Opened as draft pending review.

Summary by CodeRabbit

  • Bug Fixes

    • Improved cancellation handling during deepnote toolkit setup so cancelled installations stop cleanly and aren’t treated as failures.
    • Made the “toolkit already installed” detection more reliable to avoid incorrect success/failure outcomes during setup.
  • Tests

    • Added regression coverage to verify cancellation-token propagation through the toolkit installation workflow.
    • Expanded assertions to ensure install fast-path behavior and correct exec invocation behavior.

The pip/venv exec calls in the Deepnote toolkit installer were started without the CancellationToken, so cancellation was only checked between calls. Cancelling during a multi-minute pip install did nothing until the install finished, leaving the Stop button unresponsive.

Pass the token into every processService.exec call (and thread it through isToolkitInstalled) so cancelling now terminates the running subprocess immediately.
@linear-code

linear-code Bot commented Jun 9, 2026

Copy link
Copy Markdown

SAL-105

@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0%. Comparing base (cd1a571) to head (66a0ded).
⚠️ Report is 6 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@     Coverage Diff     @@
##   main   #409   +/-   ##
===========================
===========================
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR propagates a cancellation token through deepnote-toolkit installation subprocesses. The installer now forwards the token to venv creation, pip upgrades, toolkit version checks, package installation, and ipykernel install. It also rethrows cancellation errors in the install flow, and the kernel-spec check now looks for kernel.json. Unit tests cover token forwarding and empty-package behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer as DeepnoteToolkitInstaller
  participant ProcessService as IProcessService
  participant Filesystem as Filesystem

  Installer->>ProcessService: exec python -m venv { token }
  Installer->>ProcessService: exec pip install --upgrade { token }
  Installer->>ProcessService: exec deepnote_toolkit version probe { token }
  Installer->>Filesystem: check kernel.json exists
  Installer->>ProcessService: exec ipykernel install { token }
Loading
🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Updates Docs ⚠️ Warning The PR only changes installer code/tests; no markdown/spec docs were updated in the visible repo. Add/refresh OSS docs for cancelable installs and update the roadmap in deepnote/deepnote-internal; I can’t verify that private repo here.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: forwarding the cancellation token to toolkit installer subprocesses.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 9, 2026
@sLightlyDev sLightlyDev marked this pull request as ready for review June 9, 2026 13:36
@sLightlyDev sLightlyDev requested a review from a team as a code owner June 9, 2026 13:36
ProcessService.exec resolves with partial output when the token kills
the process (only shellExec rejects), so forwarding the token exposed
several paths that misread a cancelled exec as a domain result:

- rethrow CancellationError unwrapped from installVenvAndToolkit's
  catch so upstream isCancellationError checks suppress the error UI
  instead of showing an install failure
- make isToolkitInstalled cancellation-aware: throw on cancel after the
  probe exec instead of returning undefined, which misdiagnosed healthy
  venvs as toolkit-missing and successful installs as failed verification
- require the token parameter on isToolkitInstalled so future callers
  cannot silently reintroduce an uncancellable probe
- check for kernel.json rather than the kernelspec directory and
  re-check the token after the ipykernel exec, so a cancelled install
  cannot leave a permanently trusted partial kernelspec
- re-check the token in installAdditionalPackages before reporting
  success, and log cancellation instead of a failure message

Rewrite the unit test on the repo's ts-mockito pattern (capture/verify,
deepStrictEqual per CLAUDE.md) and cover the ensureVenvAndToolkit probe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/kernels/deepnote/deepnoteToolkitInstaller.unit.test.ts (1)

57-124: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Repeated CancellationTokenSource create/dispose boilerplate.

All three tests wrap the body in identical const cts = new CancellationTokenSource(); try {...} finally { cts.dispose(); }. Could extract a small helper/fixture, but with only 3 tests the payoff is marginal.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/kernels/deepnote/deepnoteToolkitInstaller.unit.test.ts` around lines 57 -
124, The three tests in installAdditionalPackages and ensureVenvAndToolkit
repeat the same CancellationTokenSource setup/teardown boilerplate, so factor
that pattern into a small helper or fixture in
deepnoteToolkitInstaller.unit.test.ts. Keep the helper focused on creating the
token, running the async test body, and disposing the source afterward, then
update the tests to use it while preserving the existing assertions and token
forwarding checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/kernels/deepnote/deepnoteToolkitInstaller.unit.test.ts`:
- Around line 57-124: The three tests in installAdditionalPackages and
ensureVenvAndToolkit repeat the same CancellationTokenSource setup/teardown
boilerplate, so factor that pattern into a small helper or fixture in
deepnoteToolkitInstaller.unit.test.ts. Keep the helper focused on creating the
token, running the async test body, and disposing the source afterward, then
update the tests to use it while preserving the existing assertions and token
forwarding checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f9686885-8346-41c5-abba-80b1b0da61b5

📥 Commits

Reviewing files that changed from the base of the PR and between 39a1e41 and 66a0ded.

📒 Files selected for processing (2)
  • src/kernels/deepnote/deepnoteToolkitInstaller.node.ts
  • src/kernels/deepnote/deepnoteToolkitInstaller.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/kernels/deepnote/deepnoteToolkitInstaller.node.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants